<template>
  <div class="device-parameter-container">
    <!-- 搜索区域 -->
    <el-card class="search-card">
      <el-row>
        <el-col :span="8">
          <el-input
              v-model="searchDeviceId"
              placeholder="请输入设备ID"
              clearable
              @input="handleSearchInput"
          >
            <template #append>
              <el-button @click="searchByDeviceId">
                <i class="fa fa-search"></i> 查询
              </el-button>
            </template>
          </el-input>
        </el-col>
        <el-col :span="8" :offset="8">
          <el-button type="primary" @click="resetSearch">
            <i class="fa fa-refresh"></i> 重置
          </el-button>
          <el-button type="success" @click="exportExcel" style="margin-left: 10px;">
            <i class="fa fa-download"></i> 导出Excel
          </el-button>
        </el-col>
      </el-row>
    </el-card>

    <!-- 数据表格 -->
    <el-card class="table-card">
      <div class="loading-container" v-if="loading">
        <el-loading-spinner></el-loading-spinner>
        <div class="loading-text">数据加载中...</div>
      </div>

      <el-table
          v-else
          :data="deviceParams"
          border
          stripe
          highlight-current-row
          empty-text="暂无数据"
          @row-click="handleRowClick"
          style="width: 100%; table-layout: auto;"
      >
        <el-table-column
            prop="deviceId"
            label="设备ID"
            align="center"
            sortable
        ></el-table-column>
        <el-table-column
            prop="paramName"
            label="参数名称"
            align="center"
        ></el-table-column>
        <el-table-column
            prop="paramCode"
            label="参数编码"
            align="center"
        ></el-table-column>
        <el-table-column
            prop="unit"
            label="单位"
            align="center"
        ></el-table-column>
        <el-table-column
            prop="normalMin"
            label="正常最小值"
            align="center"
        ></el-table-column>
        <el-table-column
            prop="normalMax"
            label="正常最大值"
            align="center"
        ></el-table-column>
        <el-table-column
            label="正常范围"
            align="center"
        >
          <template #default="scope">
            <el-tag :type="getRangeType(scope.row)">{{ scope.row.normalMin }} - {{ scope.row.normalMax }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column
            prop="paramValue"
            label="当前值"
            align="center"
        >
          <template #default="scope">
            <span :class="getTextClass(scope.row)">{{ scope.row.paramValue }}</span>
          </template>
        </el-table-column>
        <el-table-column
            label="状态"
            align="center"
        >
          <template #default="scope">
            <el-tag :type="getStatusType(scope.row)">{{ getStatusText(scope.row) }}</el-tag>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 详情对话框 -->
    <el-dialog
        :visible.sync="dialogVisible"
        title="设备参数详情"
        width="60%"
    >
      <el-form :model="selectedParam" label-width="120px">
        <el-form-item label="设备ID">
          <el-input v-model="selectedParam.deviceId" disabled></el-input>
        </el-form-item>
        <el-form-item label="参数名称">
          <el-input v-model="selectedParam.paramName" disabled></el-input>
        </el-form-item>
        <el-form-item label="参数编码">
          <el-input v-model="selectedParam.paramCode" disabled></el-input>
        </el-form-item>
        <el-form-item label="单位">
          <el-input v-model="selectedParam.unit" disabled></el-input>
        </el-form-item>
        <el-form-item label="正常最小值">
          <el-input v-model="selectedParam.normalMin" disabled></el-input>
        </el-form-item>
        <el-form-item label="正常最大值">
          <el-input v-model="selectedParam.normalMax" disabled></el-input>
        </el-form-item>
        <el-form-item label="当前值">
          <el-input v-model="selectedParam.paramValue" disabled></el-input>
        </el-form-item>
        <el-form-item label="数据时间">
          <el-input v-model="selectedParam.dataTime" disabled></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>


    <!-- 分页组件 -->
    <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
    >
    </el-pagination>

<!--
    &lt;!&ndash; 图表控制区域 &ndash;&gt;
    <el-card class="chart-control-card">
      <el-row :gutter="20">
        <el-col :span="8">
          <el-input
              v-model="manualDeviceId"
              placeholder="请输入设备ID"
              clearable
              @input="handleDeviceIdChange"
          />
        </el-col>
        <el-col :span="8">
          <el-select
              v-model="selectedParamName"
              placeholder="请选择参数名称"
              style="width: 100%"
              filterable
              :disabled="!hasDeviceId"
          >
            <el-option
                v-for="param in paramOptions"
                :key="param"
                :label="param"
                :value="param"
            />
          </el-select>
        </el-col>
        <el-col :span="8">
          <el-button type="primary" @click="fetchAndDrawChart">生成图表</el-button>
        </el-col>
      </el-row>
    </el-card>

    &lt;!&ndash; 图表容器 &ndash;&gt;
    <el-card class="chart-card">
      <div ref="barChart" style="width: 100%; height: 400px;"></div>
    </el-card>


-->

  </div>




</template>

<script>
import * as echarts from 'echarts';
import { utils, writeFile } from 'xlsx';

export default {
  name: 'DeviceParameterQuery',
  data() {
    return {
      currentPage: 1, // 当前页码
      pageSize: 10,   // 每页显示数量
      total: 0,       // 总记录数
      // ... 其他变量


      chartInstance: null,
      paramOptions: [], // 参数名称选项
      deviceSearchLoading: false,
      manualDeviceId: '', // 手动输入的设备ID
      hasDeviceId: false, // 标记是否已输入有效的deviceId
      socket: null, // WebSocket 实例
      selectedParamName: '',

      // 搜索条件
      searchDeviceId: '',

      // 表格数据
      deviceParams: [],
      loading: false,
      lastUpdateTime: '',

      // 详情对话框
      dialogVisible: false,
      selectedParam: {}
    };
  },
  mounted() {
    this.initWebSocket(); // 初始化WebSocket连接
  },
  beforeDestroy() {
    // 关闭WebSocket连接
    if (this.socket) {
      this.socket.close();
    }
    if (this.chartInstance) {
      this.chartInstance.dispose();
    }
  },
  methods: {
    // 根据设备ID搜索
    searchByDeviceId() {
      this.currentPage = 1; // 重置为第一页
      this.sendPageRequest(this.currentPage, this.pageSize);
    },

    // 每页显示数量改变时触发
    handleSizeChange(val) {
      this.pageSize = val;
      this.sendPageRequest(this.currentPage, this.pageSize);
    },

    // 当前页码改变时触发
    handleCurrentChange(val) {
      this.currentPage = val;
      this.sendPageRequest(this.currentPage, this.pageSize);
    },

    // 发送分页请求给后端
    sendPageRequest(page, pageSize) {
      const message = JSON.stringify({
        page,
        pageSize,
        deviceId: this.searchDeviceId || null // 添加设备ID参数
      });
      this.socket.send(message);
    },

    // 初始化WebSocket连接
    initWebSocket() {
      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      const socketUrl = `${protocol}//${window.location.host}/deviceWebSocket`;

      this.socket = new WebSocket(socketUrl);
      this.loading = true;

      this.socket.onopen = () => {
        console.log('WebSocket连接已建立');
        this.loading = false;
        // 初始化时请求第一页数据
        this.sendPageRequest(1, this.pageSize);
      };

      this.socket.onmessage = (event) => {
        try {
          const message = JSON.parse(event.data);
          console.log('收到WebSocket消息:', message);

          if (message && message.records) {
            // 更新表格数据
            this.deviceParams = message.records || [];
            this.total = message.total || 0; // 更新总记录数

            // 更新参数选项
            if (this.searchDeviceId) {
              const uniqueParams = [...new Set(this.deviceParams.map(d => d.paramName))];
              this.paramOptions = uniqueParams;
            } else {
              this.paramOptions = [];
            }

            this.lastUpdateTime = new Date().toLocaleString();
          }
        } catch (error) {
          console.error('解析WebSocket消息失败:', error);
        }
      };

      this.socket.onerror = (error) => {
        console.error('WebSocket错误:', error);
        this.$message.error('WebSocket连接错误');
        this.loading = false;
      };

      this.socket.onclose = () => {
        console.log('WebSocket连接关闭');
      };
    },

    // 导出Excel
    exportExcel() {
      console.log('触发导出');
      if (this.deviceParams.length === 0) {
        this.$message.warning('暂无数据可导出');
        return;
      }

      try {
        const exportData = this.deviceParams.map(item => ({
          '设备ID': item.deviceId?.toString() || '',
          '参数名称': item.paramName || '',
          '参数编码': item.paramCode || '',
          '单位': item.unit || '',
          '正常最小值': Number(item.normalMin) || 0,
          '正常最大值': Number(item.normalMax) || 0,
          '正常范围': `${item.normalMin || ''} - ${item.normalMax || ''}`,
          '当前值': Number(item.paramValue) || 0,
          '状态': this.getStatusText(item),
          '数据时间': item.dataTime ? new Date(item.dataTime).toLocaleString() : ''
        }));

        const worksheet = utils.json_to_sheet(exportData);
        worksheet['!cols'] = [
          { wch: 12 }, { wch: 15 }, { wch: 15 }, { wch: 8 },
          { wch: 12 }, { wch: 12 }, { wch: 15 }, { wch: 10 },
          { wch: 8 }, { wch: 20 }
        ];

        const workbook = utils.book_new();
        utils.book_append_sheet(workbook, worksheet, '设备参数数据');

        const fileName = `设备参数数据_${new Date().toLocaleDateString().replace(/\//g, '-')}.xlsx`;
        writeFile(workbook, fileName);

        this.$message.success('导出成功');
      } catch (error) {
        console.error('导出失败:', error);
        this.$message.error(`导出失败：${error.message || '未知错误'}`);
      }
    },

    // 监听设备ID输入框变化
    handleDeviceIdChange() {
      if (!this.manualDeviceId.trim()) {
        this.hasDeviceId = false;
        this.paramOptions = [];
        this.selectedParamName = '';
        return;
      }
      this.hasDeviceId = true;
    },

    // 生成图表
    fetchAndDrawChart() {
      if (!this.manualDeviceId || !this.selectedParamName) {
        this.$message.warning('请选择设备ID和参数名称');
        return;
      }

      const device = this.deviceParams.find(d =>
          d.deviceId === this.manualDeviceId &&
          d.paramName === this.selectedParamName
      );

      if (!device) {
        this.$message.error('未找到该参数对应的设备数据');
        return;
      }

      this.drawBarChart(device);
    },

    // 绘制柱状图
    drawBarChart(device) {
      const chartDom = this.$refs.barChart;
      if (!chartDom) return;

      if (this.chartInstance) {
        this.chartInstance.dispose();
      }

      this.chartInstance = echarts.init(chartDom);

      const option = {
        title: {
          text: `设备 ${device.deviceId} - 参数：${device.paramName}`
        },
        tooltip: {
          trigger: 'axis',
          formatter: '{b}<br/>{a0}: {c0}<br/>{a1}: {c1}<br/>{a2}: {c2}'
        },
        xAxis: {
          type: 'category',
          data: ['参数值']
        },
        yAxis: {
          type: 'value',
          name: device.unit
        },
        series: [
          {
            name: '最小值',
            type: 'bar',
            data: [device.normalMin],
            itemStyle: { color: '#91cc75' }
          },
          {
            name: '当前值',
            type: 'bar',
            data: [device.paramValue],
            itemStyle: { color: '#5470c6' }
          },
          {
            name: '最大值',
            type: 'bar',
            data: [device.normalMax],
            itemStyle: { color: '#facc14' }
          }
        ],
        legend: {
          data: ['最小值', '当前值', '最大值']
        }
      };

      this.chartInstance.setOption(option);
    },

    // 重置搜索
    resetSearch() {
      this.searchDeviceId = '';
      this.manualDeviceId = '';
      this.selectedDeviceId = '';
      this.selectedParamName = '';
      this.paramOptions = [];
      this.hasDeviceId = false;

      // 重置后重新加载数据
      this.currentPage = 1;
      this.sendPageRequest(1, this.pageSize);
    },

    handleSearchInput(value) {
      // 当输入框清空时自动重置
      if (value === '') {
        this.resetSearch();
      }
    },

    // 行点击事件
    handleRowClick(row) {
      this.selectedParam = { ...row };
      this.dialogVisible = true;
      this.selectedDeviceId = row.deviceId;
      const uniqueParams = [...new Set(this.deviceParams.map(d => d.paramName))];
      this.paramOptions = uniqueParams;
    },

    // 状态文本
    getStatusText(row) {
      if (row.paramValue < row.normalMin) return '偏低';
      if (row.paramValue > row.normalMax) return '偏高';
      return '正常';
    },

    // 状态类型
    getStatusType(row) {
      if (row.paramValue < row.normalMin) return 'warning';
      if (row.paramValue > row.normalMax) return 'danger';
      return 'success';
    },

    // 文本样式
    getTextClass(row) {
      if (row.paramValue < row.normalMin || row.paramValue > row.normalMax) {
        return 'text-danger';
      }
      return '';
    },

    // 范围类型
    getRangeType() {
      return 'info';
    }
  }
};
</script>

<style scoped>
.search-card {
  margin-bottom: 20px;
}

.chart-control-card {
  margin-top: 20px;
}

.table-card {
  min-height: 400px;
  position: relative;
}

.chart-card {
  margin-top: 30px;
}

.loading-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.8);
  z-index: 10;
}

.loading-text {
  margin-top: 10px;
  color: #909399;
}

.text-danger {
  color: #f56c6c;
  font-weight: bold;
}
</style>
